package com.dahuyou.tryy.too.simulate.interpreter.instructions.base;

import com.dahuyou.tryy.too.simulate.interpreter.runtime.area.Frame;
import com.dahuyou.tryy.too.simulate.interpreter.runtime.area.Slot;
import com.dahuyou.tryy.too.simulate.interpreter.runtime.area.Thread;
import com.dahuyou.tryy.too.simulate.interpreter.runtime.area.heap.methodarea.Method;

public class MethodInvokeLogic {

    public static void invokeMethod(Frame invokerFrame, Method method) {
        if (method.name.equalsIgnoreCase("returnALong")) {
            System.out.println("------invoke xxxx 指令，做如下的事情；------");
            System.out.println("1：从当前栈帧中获取对应的执行线程");
            System.out.println("2：为要执行的方法创建对应的栈帧，并将栈帧压倒线程栈，作为当前栈帧");
            System.out.println("3：如果是有入参的话，则从调用栈帧的操作数栈中弹出入参，并设置到新栈帧的局部变量表中，这样被调用方法执行时就可以通过load指令从局部变量中获取操作");
        }
        Thread thread = invokerFrame.thread();
        Frame newFrame = thread.newFrame(method);
        thread.pushFrame(newFrame);
        // 将方法需要的参数设置到新栈帧的局部变量表中
        int argSlotCount = method.argSlotCount();
        if (argSlotCount > 0) {
            for (int i = argSlotCount - 1; i >= 0; i--) {
                Slot slot = invokerFrame.operandStack().popSlot();
                newFrame.localVars().setSlot(i, slot);
            }
        }

        //hack
        if (method.isNative()) {
            if ("registerNatives".equals(method.name())) {
                thread.popFrame();
            } else {
                throw new RuntimeException("native method " + method.name());
            }
        }
    }

}
